import os
import random
import subprocess
import time

from pynput import keyboard
from pynput.keyboard import Key
from PySide6.QtCore import QThread

from common import frame_to_timecode, timecode_to_frame
from log_manager import LogManager
from python_get_resolve import GetResolve


def request_automation_permission():
    """请求自动化权限"""
    script = """
    tell application "System Events"
        try
            get every process
            return true
        on error
            return false
        end try
    end tell
    """

    try:
        # 运行 AppleScript 检查权限
        result = subprocess.run(
            ["osascript", "-e", script], capture_output=True, text=True
        )

        if "true" in result.stdout.lower():
            LogManager.log("已获得自动化权限")
            return True

        # 如果没有权限，显示系统设置
        LogManager.log("正在请求自动化权限...")
        show_settings_script = """
        tell application "System Settings"
            activate
            delay 1
            tell application "System Events"
                click menu item "隐私与安全性" of menu "前往" of menu bar 1
            end tell
        end tell
        """
        subprocess.run(["osascript", "-e", show_settings_script])
        return False

    except Exception as e:
        LogManager.log(f"请求权限时出错: {str(e)}")
        return False


class HotkeyAgent(QThread):
    AVAILABLE_TYPE = [
        "remove_frame",
        "interpolation_frame",
        "remove_subtitle_gaps",
        "move_clip",
    ]

    def __init__(self):
        super().__init__()
        self.running = False
        self.listener = None
        self.min_per_second = 3
        self.max_per_second = 5
        self.type = "remove_frame"
        # 定义修饰键映射
        self.modifier_keys = {
            "command": "command down",
            "cmd": "command down",
            "shift": "shift down",
            "option": "option down",
            "alt": "option down",
            "control": "control down",
            "ctrl": "control down",
        }
        # 定义特殊键映射
        self.special_keys = {
            "right": "124",  # 右方向键
            "left": "123",  # 左方向键
            "up": "126",  # 上方向键
            "down": "125",  # 下方向键
            "return": "36",  # 回车键
            "enter": "36",  # 回车键
            "tab": "48",  # Tab键
            "space": "49",  # 空格键
            "delete": "51",  # Delete键
            "esc": "53",  # ESC键
            ".": "47",  # 点键
            "backspace": "51",  # 退格键
        }

    def set_type(self, type):
        if type not in self.AVAILABLE_TYPE:
            raise ValueError(f"无效的类型: {type}")
        self.type = type

    def parse_time(self, time):
        """将时分秒的字符串解析为秒"""
        # 分割时间字符串
        parts = time.split(":")
        if len(parts) == 3:
            hours, minutes, seconds = map(int, parts)
            # 将时分秒转换为秒
            total_seconds = hours * 3600 + minutes * 60 + seconds
            return total_seconds
        elif len(parts) == 2:
            minutes, seconds = map(int, parts)
            # 将分秒转换为秒
            total_seconds = minutes * 60 + seconds
            return total_seconds
        elif len(parts) == 1:
            seconds = int(parts[0])
            return seconds
        else:
            LogManager.log("时间格式不正确")
            return 0

    def format_time(self, time):
        """将秒数格式化为时分秒"""
        minutes = (time % 3600) // 60
        seconds = time % 60
        return f"{minutes:02d}{seconds:02d}"

    def simulate_key_press(self, key, modifiers=None):
        """
        模拟按键
        :param key: 要按下的键或特殊键名称
        :param modifiers: 要同时按下的功能键列表，例如 ['command', 'shift']
        """
        try:
            LogManager.log(
                f"准备模拟按键: {key}"
                + (f" 配合功能键: {modifiers}" if modifiers else "")
            )

            # 构建修饰键字符串
            modifier_list = []
            if modifiers:
                for mod in modifiers:
                    mod = mod.lower()
                    if mod in ["command", "cmd"]:
                        modifier_list.append("command")
                    elif mod in ["option", "alt"]:
                        modifier_list.append("option")
                    elif mod == "shift":
                        modifier_list.append("shift")
                    elif mod in ["control", "ctrl"]:
                        modifier_list.append("control")

            # 使用 AppleScript 模拟按键
            script_lines = ['tell application "System Events"', "    try"]

            # 检查是否是特殊键
            key_lower = key.lower() if isinstance(key, str) else key
            if key_lower in self.special_keys:
                # 使用 key code 来模拟特殊键
                if modifier_list:
                    modifiers_str = " down, ".join(modifier_list)
                    script_lines.append(
                        f"        key code {self.special_keys[key_lower]}"
                        f" using {{{modifiers_str} down}}"
                    )
                else:
                    script_lines.append(
                        f"        key code {self.special_keys[key_lower]}"
                    )
            else:
                # 普通键使用 keystroke
                if modifier_list:
                    modifiers_str = " down, ".join(modifier_list)
                    script_lines.append(
                        f'        keystroke "{key}" using {{{modifiers_str} down}}'
                    )
                else:
                    script_lines.append(f'        keystroke "{key}"')

            # 添加结尾
            script_lines.extend(
                [
                    '        return "success"',
                    "    on error errMsg",
                    "        return errMsg",
                    "    end try",
                    "end tell",
                ]
            )

            script = "\n".join(script_lines)
            # 将脚本转换为 UTF-8 编码的字节字符串
            script = script.encode('utf-8')

            result = subprocess.run(
                ["osascript", "-e", script],
                capture_output=True,
                text=True,
                encoding='utf-8'  # 指定输入输出编码为 UTF-8
            )

            if "success" in result.stdout:
                LogManager.log("按键模拟成功")
            else:
                LogManager.log(f"模拟按键失败: {result.stdout.strip()}")

        except Exception as e:
            LogManager.log(f"模拟按键失败: {str(e)}")
        finally:
            time.sleep(0.1)

    def do_remove_frame(self):
        """抽帧"""
        _, currentTimeline = self.resolve_get_current()
        length = currentTimeline.GetEnd() - currentTimeline.GetStart()
        current_time = 0
        while current_time < length and self.running:
            current_time += random.randint(self.min_per_second, self.max_per_second)
            self.simulate_key_press("=")
            time_str = self.format_time(current_time)
            LogManager.log(time_str)
            # self.simulate_key_press(time_str)
            for c in time_str:
                self.simulate_key_press(c)
            self.simulate_key_press("0")
            self.simulate_key_press("0")
            self.simulate_key_press("enter")
            self.simulate_key_press("b", ["command"])
            self.simulate_key_press("right")
            self.simulate_key_press("[", ["command", "shift"])

        os.system("say '完成'")

    def do_interpolation_frame(self):
        self.simulate_key_press("y", ["alt"])
        self.simulate_key_press(".")
        self.simulate_key_press("left")
        self.simulate_key_press("left")
        self.simulate_key_press("left")
        self.simulate_key_press("v", ["command"])

    def do_move_clip(self):
        _, currentTimeline = self.resolve_get_current()
        save_timecode = currentTimeline.GetCurrentTimecode()
        self.simulate_key_press("x", ["command"])
        self.simulate_key_press("v", ["command"])
        currentTimeline.SetCurrentTimecode(save_timecode)

    def do_remove_subtitle_gaps(self):
        _, currentTimeline = self.resolve_get_current()
        fps = currentTimeline.GetSetting("timelineFrameRate")
        LogManager.log(f"当前时间线: {currentTimeline.GetName()}")
        LogManager.log(f"当前时间线: fps {fps}")
        srt_items = currentTimeline.GetItemListInTrack("subtitle", 1)
        LogManager.log(f"当前时间线: {currentTimeline.GetName()}")
        last_item = None
        start_timecode = currentTimeline.GetCurrentTimecode()
        start_frame = timecode_to_frame(start_timecode, fps)
        for item in srt_items:
            LogManager.log(f"字幕项: {item.GetName()}")
            LogManager.log(f"字幕项: start {item.GetStart()}")
            LogManager.log(f"字幕项: end {item.GetEnd()}")
            if last_item:
                if item.GetStart() > start_frame and item.GetStart() - last_item.GetEnd() > 1:
                    LogManager.log(
                        f"字幕项: {item.GetName()} 与 {last_item.GetName()} 有间隔"
                    )
                    self.simulate_key_press("a", ["shift", "command"])
                    last_timecode = frame_to_timecode(last_item.GetEnd(), fps)
                    LogManager.log(f"字幕项: {item.GetName()} 时间码: {last_timecode}")
                    current_timecode = frame_to_timecode(item.GetStart() - 1, fps)
                    currentTimeline.SetCurrentTimecode(last_timecode)
                    self.simulate_key_press("i")
                    currentTimeline.SetCurrentTimecode(current_timecode)
                    self.simulate_key_press("o")
                    self.simulate_key_press("backspace", ["shift"])
                    # time.sleep(0.5)
            last_item = item

    def resolve_get_current(self):
        resolve = GetResolve()
        projectManager = resolve.GetProjectManager()
        # 获取当前打开的项目
        currentProject = projectManager.GetCurrentProject()
        currentTimeline = currentProject.GetCurrentTimeline()
        return currentProject, currentTimeline

    def test_resolve(self, timecode="01:14:16:08"):
        _, currentTimeline = self.resolve_get_current()
        LogManager.log(currentTimeline.GetName())
        currentTimecode = currentTimeline.GetCurrentTimecode()
        LogManager.log(currentTimecode)
        currentTimeline.SetCurrentTimecode(timecode)

    def run(self):
        LogManager.log(f"开始执行 {self.type} 任务")
        func = getattr(self, f"do_{self.type}")
        func()
        LogManager.log(f"完成 {self.type} 任务")

    def stop_task(self):
        self.running = False

    def on_press(self, key):
        """当按下按键时的回调函数"""
        try:
            if key == Key.esc:  # 检测是否按下F1
                # 结束任务
                LogManager.log("结束任务")
                self.terminate()
            elif hasattr(key, "vk") and key.vk == 0x32:
                # 启动线程，执行 run 函数
                self.start()
        except Exception as e:
            LogManager.log(f"处理按键事件失败: {str(e)}")

    def start_listen(self, type):
        """启动监听"""
        self.set_type(type)
        # 创建键盘监听器
        self.listener = keyboard.Listener(on_press=self.on_press)
        self.listener.start()

        try:
            self.listener.join()
        except KeyboardInterrupt:
            LogManager.log("\n检测到Ctrl+C，正在退出...")
            self.stop_listen()

    def stop_listen(self):
        """停止监听"""
        if self.listener:
            self.listener.stop()
        self.terminate()


if __name__ == "__main__":
    agent = HotkeyAgent()
    type_index = None
    while type_index not in range(len(agent.AVAILABLE_TYPE)):
        print("请选择任务类型:")
        for i, t in enumerate(agent.AVAILABLE_TYPE):
            print(f"  {i}: {t}")
        type_index = int(input())
    agent.start_listen(agent.AVAILABLE_TYPE[type_index])
